Lambda 表达式

概述

Lambda 表达式是 C++11 引入的一个强大特性,它允许我们在代码中定义匿名函数。Lambda 表达式可以捕获其所在作用域中的变量,并且可以直接在需要的地方定义和使用,而不需要预先定义一个命名函数。

基本语法

Lambda 表达式的基本语法如下:

[捕获列表](参数列表) -> 返回类型 { 函数体 }
  • 捕获列表:用于捕获外部作用域中的变量。
  • 参数列表:与普通函数的参数列表相同。
  • 返回类型:指定 Lambda 表达式的返回类型。如果省略,编译器会自动推断。
  • 函数体:Lambda 表达式的具体实现。

示例 1:简单的 Lambda 表达式

#include <iostream>

int main() {
    auto greet = []() { std::cout << "Hello, World!" << std::endl; };
    greet();  // 输出: Hello, World!
    return 0;
}

在这个例子中,greet 是一个 Lambda 表达式,它不接受任何参数,也没有捕获任何外部变量。

示例 2:带参数的 Lambda 表达式

#include <iostream>

int main() {
    auto add = [](int a, int b) { return a + b; };
    std::cout << add(3, 4) << std::endl;  // 输出: 7
    return 0;
}

在这个例子中,add 是一个 Lambda 表达式,它接受两个参数 a 和 b,并返回它们的和。

示例 3:捕获外部变量

#include <iostream>

int main() {
    int x = 10;
    auto multiply = [x](int a) { return x * a; };
    std::cout << multiply(5) << std::endl;  // 输出: 50
    return 0;
}

在这个例子中,Lambda 表达式 multiply 捕获了外部变量 x,并在函数体中使用了它。

捕获列表

捕获列表用于指定 Lambda 表达式如何访问其所在作用域中的变量。捕获列表可以包含以下几种形式:

  • []:不捕获任何变量。
  • [&]:按引用捕获所有外部变量。
  • [=]:按值捕获所有外部变量。
  • [x]:按值捕获变量 x。
  • [&x]:按引用捕获变量 x。
  • [&, x]:按引用捕获所有变量,但 x 按值捕获。
  • [=, &x]:按值捕获所有变量,但 x 按引用捕获。

示例 4:按引用捕获

#include <iostream>

int main() {
    int x = 10;
    auto increment = [&x]() { x++; };
    increment();
    std::cout << x << std::endl;  // 输出: 11
    return 0;
}

在这个例子中,Lambda 表达式 increment 按引用捕获了变量 x,因此可以在函数体中修改它的值。

示例 5:按值捕获

#include <iostream>

int main() {
    int x = 10;
    auto print = [x]() { std::cout << x << std::endl; };
    x = 20;
    print();  // 输出: 10
    return 0;
}

在这个例子中,Lambda 表达式 print 按值捕获了变量 x,因此在函数体中使用的 x 是捕获时的值,而不是最新的值。

返回类型

Lambda 表达式的返回类型可以显式指定,也可以由编译器自动推断。如果 Lambda 表达式的主体包含多个返回语句,或者返回类型不明确,建议显式指定返回类型。

示例 6:显式指定返回类型

#include <iostream>

int main() {
    auto divide = [](double a, double b) -> double {
        if (b == 0) {
            return 0;
        }
        return a / b;
    };
    std::cout << divide(10.0, 2.0) << std::endl;  // 输出: 5
    std::cout << divide(10.0, 0.0) << std::endl;  // 输出: 0
    return 0;
}

在这个例子中,Lambda 表达式 divide 显式指定了返回类型为 double。

实践练习

练习 1:使用 Lambda 表达式实现排序

编写一个程序,使用 Lambda 表达式对一个整数数组进行排序。

#include <iostream>
#include <vector>
#include <algorithm>

int main() {
    std::vector<int> numbers = {5, 3, 8, 1, 2};
    std::sort(numbers.begin(), numbers.end(), [](int a, int b) {
        return a < b;
    });
    for (int num : numbers) {
        std::cout << num << " ";
    }
    std::cout << std::endl;  // 输出: 1 2 3 5 8
    return 0;
}

练习 2:使用 Lambda 表达式计算数组元素的和

编写一个程序,使用 Lambda 表达式计算一个整数数组中所有元素的和。

#include <iostream>
#include <vector>
#include <numeric>

int main() {
    std::vector<int> numbers = {1, 2, 3, 4, 5};
    int sum = std::accumulate(numbers.begin(), numbers.end(), 0, [](int a, int b) {
        return a + b;
    });
    std::cout << "Sum: " << sum << std::endl;  // 输出: Sum: 15
    return 0;
}

总结

Lambda 表达式是 C++ 中一个非常强大的工具,它允许我们在代码中定义匿名函数,并且可以捕获外部作用域中的变量。通过 Lambda 表达式,我们可以编写更加简洁和灵活的代码。希望本教程能够帮助你理解和掌握 Lambda 表达式的使用。